package com.yiboshi.rehrs.manager;

import cn.hutool.core.lang.Pair;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yiboshi.rehrs.domain.entity.ZhongUser;
import com.yiboshi.rehrs.domain.entity.ZhongUserImage;
import com.yiboshi.rehrs.domain.service.IZhongUserImageService;
import com.yiboshi.rehrs.domain.service.IZhongUserService;
import com.yiboshi.rehrs.exception.ZhongException;
import com.yiboshi.rehrs.exception.ZyantExceptionUtils;
import com.yiboshi.rehrs.feign.PosterFeignInterceptor;
import com.yiboshi.rehrs.helper.HelperJinshe;
import com.yiboshi.rehrs.helper.HttpHelper;
import com.yiboshi.rehrs.helper.RedisLocker;
import com.yiboshi.rehrs.helper.ZhongConfigHelper;
import com.yiboshi.rehrs.param.CallRecord;
import com.yiboshi.rehrs.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author jack 2025/3/26
 */
@Component
@Slf4j
public class ZhongYouManager {

    //@Autowired
    //PosterFeign posterFeign;
    @Autowired
    ZhongConfigHelper configHelper;

    @Autowired
    HttpHelper httpHelper;

    @Autowired
    IZhongUserService zhongUserService;

    @Autowired
    IZhongUserImageService zhongUserImageService;

    @Autowired
    RedisLocker redisLocker;

    @Autowired
    StringRedisTemplate stringRedisTemplate;


    public JSONObject ticketvalidator(ZhongUser zhongUser, Object o) {
        //{"waybillNo":"8425353790511","informDate":"TODAY"}
        JSONObject jsonObject = httpHelper.sendPost("/pdalogin/p/common/ticketvalidator", zhongUser, new JSONObject());
        if (jsonObject == null) {
            return null;
        }
        return jsonObject.getJSONObject("obj");
        //JSONObject jsonObject = posterFeign.querywaybill(end);
        //{"msg":"成功","obj":"{\"waybillNo\":\"1367953673522\",\"name\":\"王艳锋\",\"mobile\":\"18092454473\",\"addr\":\"江苏省苏州市昆山市江苏苏州市昆山市长江南路新城域花园57栋三单元一楼\",\"callTime\":1742973956000,\"talkTime\":\"16\",\"informState\":\"3\",\"failReason\":\"\",\"dlvModeRequirement\":\"\",\"appreciationType\":[{\"apctType\":\"密码投递\",\"content\":\"妥投邮件时需让收件人提供密码。\"}],\"dlvNotice\":[],\"isPwdDelivery\":1,\"projectId\":\"isForcePhone\",\"ecommerceNo\":\"DKH\",\"phoneResults\":\"已电联16S\",\"aiCallNotes\":\"非配置产品不允许智能外呼！\",\"canAiCallFlag\":\"0\",\"oriCsInfo\":\"李威_18163786699\",\"bizProductNo\":\"112104102300991\",\"starsPosition\":\"\"}","resCode":"A00001"}
        //return Optional.ofNullable(jsonObject.getJSONObject("obj")).orElse(null);

    }

    public Pair<ZhongUser, String> logonByFace(ZhongUser zhongUser, String faceImage) {
        faceImage = CommonUtil.buildLoginImageBase64(faceImage);
        JSONObject end = JSONBuilder.start("person_no", zhongUser.getAccount())
                .put("image_face", faceImage)
                .put("multiple_valued", "0,0").end();
        JSONObject jsonObject = null;

        try {
            jsonObject = httpHelper.sendPost("/pdalogin/p/common/loginbyusrface", zhongUser, end);
        } catch (ZhongException e) {
            String message = e.getMessage();
            return Pair.of(zhongUser, message);
        }

        //JSONObject jsonObject = posterFeign.loginByFace(end);
        if (jsonObject == null) {
            return Pair.of(zhongUser, "验证失败");
        }
        //log.info("loginByFace zhongUser:{} res:{}",zhongUser.getAccount(),jsonObject);
        JSONObject userJSON = Optional.ofNullable(jsonObject).map(o -> o.getJSONObject("obj")).map(o -> o.getJSONObject("user")).orElse(null);
        if (userJSON == null) {
            return Pair.of(zhongUser, jsonObject.getString("msg"));
        }
        log.info("logonbyface:userJSON={}", userJSON);
        zhongUser.setToken(userJSON.getString("token"));
        zhongUser.setFullname(userJSON.getString("person_name"));
        zhongUser.setSimpleNameCn(userJSON.getString("simple_name_cn"));
        zhongUser.setTelephone(userJSON.getString("telephone"));
        zhongUser.setOrgLatitude(userJSON.getString("org_latitude"));
        zhongUser.setOrgLongitude(userJSON.getString("org_longitude"));
        zhongUser.setOrgNo(userJSON.getString("org_no"));




        return Pair.of(zhongUser, jsonObject.getString("msg"));
    }

    static JSONObject queryListJSON = JSON.parseObject("{\"waybillState\":\"a\",\"pageNo\":\"\",\"waybillNo\":\"\",\"businessProductCode\":\"\",\"importRegionDate\":\"\",\"dlvState\":\"\",\"orderTag\":\"1\",\"queryType\":0}");

    public JSONArray findpdasignWaybillinfoNew(ZhongUser zhongUser, String waybillState) {
        try {
            JSONObject jsonObjectReq = new JSONObject();
            ;
            jsonObjectReq.putAll(queryListJSON);
            if (StrUtils.isNotBlank(waybillState)) {
                jsonObjectReq.put("waybillState", waybillState);
            } else {
                jsonObjectReq.put("waybillState", "a");
            }
            JSONObject jsonObject = httpHelper.sendPost("/delivery-app/p/delivery/pdataskquery/findpdasignwaybillinfonew.do", zhongUser, jsonObjectReq);
            //JSONObject jsonObject = posterFeign.findpdasignwaybillinfonew(queryListJSON);
            return Optional.ofNullable(jsonObject).map(o -> o.getString("obj"))
                    .filter(s -> s.startsWith("{")).map(s -> JSON.parseObject(s))
                    .map(o -> o.getJSONArray("list")).orElse(new JSONArray());
        } catch (Exception e) {
            String msg = e.getMessage();
            if (msg != null && msg.contains("无邮件信息")) {
                return new JSONArray();
            }
            throw e;
        }

    }

    //waybillNo mobile
    public JSONObject queryWaybill(ZhongUser zhongUser, String waybillNo) {
        //{"waybillNo":"8425353790511","informDate":"TODAY"}
        JSONObject end = JSONBuilder.start("waybillNo", waybillNo)
                .put("informDate", "TODAY")
                .end();
        JSONObject jsonObject = httpHelper.sendPost("/delivery-app/p/delivery/cloudcall/querywaybill", zhongUser, end);
        //JSONObject jsonObject = posterFeign.querywaybill(end);
        //log.info("account:{} queryWaybill waybillNo:{} res:{}",zhongUser.getAccount(),waybillNo,jsonObject);
        //{"msg":"成功","obj":"{\"waybillNo\":\"1367953673522\",\"name\":\"王艳锋\",\"mobile\":\"18092454473\",\"addr\":\"江苏省苏州市昆山市江苏苏州市昆山市长江南路新城域花园57栋三单元一楼\",\"callTime\":1742973956000,\"talkTime\":\"16\",\"informState\":\"3\",\"failReason\":\"\",\"dlvModeRequirement\":\"\",\"appreciationType\":[{\"apctType\":\"密码投递\",\"content\":\"妥投邮件时需让收件人提供密码。\"}],\"dlvNotice\":[],\"isPwdDelivery\":1,\"projectId\":\"isForcePhone\",\"ecommerceNo\":\"DKH\",\"phoneResults\":\"已电联16S\",\"aiCallNotes\":\"非配置产品不允许智能外呼！\",\"canAiCallFlag\":\"0\",\"oriCsInfo\":\"李威_18163786699\",\"bizProductNo\":\"112104102300991\",\"starsPosition\":\"\"}","resCode":"A00001"}
        return Optional.ofNullable(jsonObject).map(o -> o.getJSONObject("obj")).orElse(null);
    }


    public boolean updatePhone(ZhongUser zhongUser, String waybillNo, String phoneNum) {
        //{"waybillNo":"8425353790511","informDate":"TODAY"}
        JSONObject end = JSONBuilder.start("waybillNo", waybillNo)
                .put("phoneNum", phoneNum)
                .put("typeFlag", "1")
                .end();
        JSONObject jsonObject = httpHelper.sendPost("/delivery-app/p/delivery/cloudcall/updatephone", zhongUser, end);
        //JSONObject jsonObject = posterFeign.updatephone(end);
        log.info("updatePhone waybillNo:{} phoneNum:{} res:{}", waybillNo, phoneNum, jsonObject);
        return Optional.ofNullable(jsonObject).map(o -> o.getString("resCode")).map(s -> "A00001".equalsIgnoreCase(s)).orElse(false);
    }

    public boolean changesubstitutionorg(ZhongUser zhongUser, String substitutionorg) {
        //{"waybillNo":"8425353790511","informDate":"TODAY"}
        JSONObject end = JSONBuilder.start("substitutionorg", substitutionorg)
                .end();
        JSONObject jsonObject = httpHelper.sendPost("/pdalogin/p/common/changesubstitutionorg", zhongUser, end);
        //JSONObject jsonObject = posterFeign.updatephone(end);
        log.info("changesubstitutionorg substitutionorg:{}", substitutionorg);
        return Optional.ofNullable(jsonObject).map(o -> o.getString("resCode")).map(s -> "A00001".equalsIgnoreCase(s)).orElse(false);
    }


    ///pdalogin/p/common/putOrgInfo
    public boolean putOrgInfo(ZhongUser zhongUser) {
        JSONObject jsonObject = JSONObject.parseObject("{\"groupCode\":\"5327A001\",\"groupName\":\"\",\"orgCode\":\"53270003\",\"orgName\":\"\",\"workshopCode\":\"WS53270999\",\"workshopName\":\"\",\"dataSoure\":\"0\",\"seatCode\":\"\",\"seatName\":\"\"}");
        try{
            JSONObject resJSON = httpHelper.sendPost("/pdalogin/p/common/putOrgInfo", zhongUser, jsonObject.toJSONString().getBytes(),helperJinshe);
            return Optional.ofNullable(resJSON).map(o -> o.getString("resCode")).map(s -> "A00001".equalsIgnoreCase(s)).orElse(false);
        }catch (Exception e){
            log.error("putOrgInfo error",e);
            return false;
        }
    }

    public JSONObject traceInfoQuery(ZhongUser zhongUser, String waybillNo) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("waybillNo", waybillNo);
        JSONObject resJSON = httpHelper.sendPost("/pcs-tc-app/p/traceInfo/query", zhongUser, jsonObject.toJSONString().getBytes(),helperJinshe);
        return resJSON;
        //return Optional.ofNullable(resJSON).map(o->o.getString("resCode")).map(s->"A00001".equalsIgnoreCase(s)).orElse(false);
    }


    public boolean newCallAndFile(ZhongUser zhongUser, CallRecord newCallAndFile) {

        //callTime=2025-03-27+15%3A26%3A04&inFlag=3&isConnect=1&mobile=15501338645-2806&oriCsInfo=&projectId=&returnCable=0&talkTime=30%E7%A7%92&waybillNo=9878449089977&whetherAllowRecording=1&
        //talkTime=21%E7%A7%92&isConnect=1&mobile=13862602348&oriCsInfo=&returnCable=0&fileMd5=&projectId=&whetherAllowRecording=1&inFlag=3&callTime=2025-03-25+16%3A19%3A41&waybillNo=1338155801621

        //zy:
        //talkTime=2%E7%A7%92&isConnect=1&mobile=15051666861&oriCsInfo=&fileMd5=&whetherAllowRecording=1&inFlag=3&typeFlag=1&returnCable=0&projectId=&callTime=2025-04-01%2016%3A51%3A34&waybillNo=9460090604841
        //zy
        try {
            newCallAndFile.setOriCsInfo("");
            newCallAndFile.setReturnCable("0");
            newCallAndFile.setProjectId("");
            newCallAndFile.setFileMd5("");
            //newCallAndFile.setWhetherAllowRecording("0");
            newCallAndFile.setTypeFlag("");
            PosterFeignInterceptor.setHeader(zhongUser);
            String s1 = JSON.toJSONString(newCallAndFile);
            Map<String, String> objectObjectMap = JacksonUtils.toMap(s1, String.class, String.class);
            String query = query(objectObjectMap);
            //log.info("newCallAndFile query:{}",query);
            JSONObject jsonObject = httpHelper.sendPost("/delivery-app/p/delivery/cloudcall/newCallAndFile", zhongUser, query);
            //HttpResponse httpResponse = HttpClientUtils.doPostProxy("http://211.156.197.65/delivery-app/p/delivery/cloudcall/newCallAndFile", stringMap, query.getBytes(),configHelper.getProxy());
            //JSONObject jsonObject = HttpClientUtils.toJson(httpResponse);
            //log.info("newCallAndFile account:{},no:{}  res:{}",zhongUser.getAccount(),newCallAndFile.getWaybillNo() ,jsonObject);

            boolean success = Optional.ofNullable(jsonObject).map(o -> o.getString("resCode")).map(s -> "A00001".equalsIgnoreCase(s)).orElse(false);
            log.info("newCallAndFile account:{},no:{},res:{}， 参数:{} ",
                    zhongUser.getAccount(), newCallAndFile.getWaybillNo()
                    , success ? "记录成功" : "失败"
                    , JSONObject.toJSONString(newCallAndFile)

            );
            return success;
        } catch (Exception e) {
            if (e.getMessage().contains("不存在此邮件号码")) {
                return true;
                //不存在此邮件号码
            }
            log.error("newCallAndFile account:{}", zhongUser.getAccount(), e);
            return false;
        }

    }

    public String query(Map<String, String> objectObjectMap) {
        StringBuilder stringBuilder = new StringBuilder();
        objectObjectMap.forEach((k, v) -> {
            if (StrUtils.isBlank(v)) {
                v = "";
            } else {
                v = encodeURIComponent(v);
            }
            stringBuilder.append(k).append("=").append(v).append("&");
        });
        return stringBuilder.toString();
    }


    public static String encodeURIComponent(String input) {
        try {
            // 使用 URLEncoder.encode，并替换 "+" 为 "%20"
            return URLEncoder.encode(input, StandardCharsets.UTF_8.toString())
                    .replaceAll("\\+", "%20")  // 将 "+" 替换为 "%20"
                    .replaceAll("\\%21", "!")  // 保留 "!"
                    .replaceAll("\\%27", "'")  // 保留 "'"
                    .replaceAll("\\%28", "(")  // 保留 "("
                    .replaceAll("\\%29", ")")  // 保留 ")"
                    .replaceAll("\\%7E", "~"); // 保留 "~"
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Encoding failed", e);
        }
    }

    //talkTime=2%E7%A7%92&isConnect=0&mobile=15051666861&oriCsInfo=&fileMd5=&whetherAllowRecording=1&inFlag=3&typeFlag=1&returnCable=0&projectId=&callTime=2025-04-01%2016%3A51%3A34&waybillNo=9460090604841
    public static void main(String[] args) throws UnsupportedEncodingException {
        LocalDateTime now = LocalDateTime.now();
        //2025-04-01%2016%3A51%3A34 zhongyou
        //2025-04-02%2011%3A19%3A39
        String str = DateUtils.dateTimeToStr(now, DateUtils.SQL_TIME);
        String decode1 = encodeURIComponent(str);
        String decode2 = URLEncoder.encode(str, StandardCharsets.UTF_8.toString());
        //decode = encodeURIComponent("25秒");
        System.out.println(decode1);
        System.out.println(decode2);
    }


    @Autowired
    HelperJinshe helperJinshe;

    public JSONObject noTokenAccessSendAuthCodeByUsr(JSONObject jsonObject) {
        return null;


    }

    public ZhongUser initTraceQueryInfo() {
        String key = "system:init_trace";//轨迹查询使用的账号
        String account = stringRedisTemplate.opsForValue().get(key);
        account = StrUtils.isBlank(account)?"2000721200020":account;
        String redisKey = "system:init_trace_"+account;
        ZhongUser byCache10Min = CacheUtils.getByCache10Min(redisKey, ZhongUser.class);
        if(byCache10Min==null){
            String redisCacheStr = stringRedisTemplate.opsForValue().get(redisKey);
            if(StrUtils.isNotBlank(redisCacheStr)){
                byCache10Min = JSON.parseObject(redisCacheStr,ZhongUser.class);
                CacheUtils.putByCache10Min(redisKey,byCache10Min);
            }else{
                if(!redisLocker.tryLock(redisKey, 60)){
                    return null;
                }
                ZhongUser sunOne = zhongUserService.getOne(account, 0);
                ZhongUserImage sunImage = zhongUserImageService.getOne(account);
                Pair<ZhongUser, String> zhongUserStringPair = this.logonByFace(sunOne, sunImage.getImage());
                byCache10Min = zhongUserStringPair.getKey();
                String token = byCache10Min.getToken();
                ZyantExceptionUtils.e(StrUtils.isBlank(token),"初始化轨迹查询用户token为空");
                boolean success = this.putOrgInfo(byCache10Min);
               if(success){
                   CacheUtils.putByCache10Min(redisKey,byCache10Min);
                   stringRedisTemplate.opsForValue().set(redisKey,JSON.toJSONString(byCache10Min),12, TimeUnit.HOURS);
                   redisLocker.updateLockTime(redisKey, 300 + AperStringUtils.randomNum(300));
                   redisLocker.updateLockTime(key,400);
                   return byCache10Min;
               }else{
                   CacheUtils.delByCache10Min(redisKey,ZhongUser.class);
                   stringRedisTemplate.delete(redisKey);
                   redisLocker.updateLockTime(redisKey,10);
                   return null;
               }

            }
        }
        //心跳
        boolean success = redisLocker.tryLock(key, 300 + AperStringUtils.randomNum(300));
        if(success){
            boolean isOK = false;
            try {
                JSONObject ticketvalidator = this.ticketvalidator(byCache10Min, null);
                String s = Optional.ofNullable(ticketvalidator)
                        .map(o -> o.getString("person_no")).orElse("");
                isOK = s.equals(account);
            }catch (Exception e){
                log.info("轨迹查询-心跳检查错误,{}",e.getMessage());
            }
            if(isOK){
                CacheUtils.putByCache10Min(key,byCache10Min);
            }else{
                redisLocker.updateLockTime(key,100);
                CacheUtils.delByCache10Min(redisKey,ZhongUser.class);
                stringRedisTemplate.delete(redisKey);
                redisLocker.delLock(redisKey);
                return null;
            }
        }
        return byCache10Min;
    }

    /**{

     "signPersonIdType": "01",
     "signType": "20",
     "postageTotal": "0",
     "paymentType": "1",
     "codAmount": "0",
     "address": "",
     "reserved33": "跳转复制",
     "receiptFlag": "1",
     "signPersonName": "1",
     "productReachArea": "4",
     "signPersonId": "532328199903270925",
     "waybillNo": "1300786842215"
     }*/
    public JSONObject singleDeliver(ZhongUser zhongUser, String waybillNo) {
        JSONObject end = JSONBuilder
                .start("signPersonIdType", "01")
                .put("signType","10")
                .put("postageTotal","0")
                .put("paymentType","1")
                .put("codAmount","0")
                .put("reserved33","跳转复制")
                .put("receiptFlag","1")
                .put("productReachArea","4")
                .put("signPersonId",AperStringUtils.generateRandomIdCard())
                .put("waybillNo",waybillNo)
                .put("agentSignRelation","20")
                .put("signPersonName","菜鸟驿站")
                .end();
        JSONObject jsonObject = httpHelper.sendOriginPost("/delivery-app/p/pdasignwaybillFeedback/singleDeliver", zhongUser, end);
        //JSONObject jsonObject = posterFeign.updatephone(end);
        log.info("changesubstitutionorg substitutionorg:{}", end);
        return jsonObject;

    }

}
